﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cesave.Domain.PermisosModule.Entities;
using System.ComponentModel;
using Cesave.Application.Permisos.ServiceAgent;
using System.Windows.Forms;
using Cesave.Domain.Core.Entities;

namespace Cesave.Presentation.Permisos.WinForms.Client.ViewModels.Catalogs.Areas
{
    /// <summary>
    /// Manejo de secciones de área de influencia.
    /// </summary>
    public partial class AreasViewModel
    {
        #region Private properties

        /// <summary>
        /// Lista de secciones de área.
        /// </summary>
        private List<AreaSeccion> _areaSecciones;

        /// <summary>
        /// Sección de área seleccionada en la vista.
        /// </summary>
        private AreaSeccion _areaSeccion;

        #endregion

        #region Public properties

        /// <summary>
        /// Lista de secciones de área.
        /// </summary>
        public List<AreaSeccion> AreaSecciones
        {
            get
            {
                return _areaSecciones;
            }
            private set
            {
                _areaSecciones = value;
                if (_areaSecciones != null)
                    RaisePropertyChanged("AreaSecciones");
            }
        }

        /// <summary>
        /// Sección de área seleccionada en la vista.
        /// </summary>
        public AreaSeccion AreaSeccion
        {
            get
            {
                return _areaSeccion;
            }
            private set
            {
                _areaSeccion = value;
                if (_areaSeccion != null)
                    RaisePropertyChanged("AreaSeccion");
            }
        }

        /// <summary>
        /// Determina si ya se ha seleccionado una sección de área.
        /// </summary>
        public bool IsAreaSeccionReady
        {
            get
            {
                return AreaSeccion != null;
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Carga las secciones de área correspondientes a la junta.
        /// </summary>
        private void LoadAreaSecciones()
        {
            StartWaiting();
            using (BackgroundWorker worker = new BackgroundWorker())
            {
                worker.DoWork += (sender, e) =>
                {
                    using (PermisosModuleServiceWrapper service = new PermisosModuleServiceWrapper())
                    {
                        e.Result = service.FindAreaSeccionesByJuntaAndArea(_pusSettings.Junta.JuntaGuid, Area.AreaGuid);
                    }
                };
                worker.RunWorkerCompleted += (sender, e) =>
                {
                    EndWaiting();
                    if (!e.Cancelled && e.Error == null)
                        AreaSecciones = e.Result as List<AreaSeccion>;
                    else if (e.Error != null)
                        ShowMessage(e.Error.Message);
                };
                worker.WorkerSupportsCancellation = true;
                worker.RunWorkerAsync();
            }
        }

        #endregion

        #region Event methods

        /// <summary>
        /// Envía los cambios realizados a las secciones del área.
        /// </summary>
        private void SaveAreaSecciones(object s, EventArgs args)
        {
            StartWaiting();
            using (BackgroundWorker worker = new BackgroundWorker())
            {
                worker.DoWork += (sender, e) =>
                {
                    using (PermisosModuleServiceWrapper service = new PermisosModuleServiceWrapper())
                    {
                        AreaSecciones.ForEach(areaSeccion =>
                        {
                            if (areaSeccion.ChangeTracker.State == ObjectState.Added)
                                service.AddAreaSeccion(areaSeccion);
                            else
                                service.ChangeAreaSeccion(areaSeccion);
                            areaSeccion.AcceptChanges();
                        });
                    }
                };
                worker.RunWorkerCompleted += (sender, e) =>
                {
                    EndWaiting();
                    if (!e.Cancelled && e.Error == null)
                        LoadAreas();
                    else if (e.Error != null)
                        ShowMessage(e.Error.Message);
                };
                worker.WorkerSupportsCancellation = true;
                worker.RunWorkerAsync();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void AddNewAreaSeccion(object sender, EventArgs e)
        {
            _view.areaSeccionesBindingSource.AddingNew += AddingNewAreaSeccion;
            _view.areaSeccionesBindingSource.AddNew();
        }

        /// <summary>
        /// 
        /// </summary>
        private void AddingNewAreaSeccion(object sender, AddingNewEventArgs e)
        {
            AreaSeccion = new AreaSeccion
            {
                AreaGuid = Area.AreaGuid,
                AreaId = Area.AreaId,
                AreaSeccionGuid = Guid.NewGuid(),
                AreaSeccionId = 0,
                JuntaGuid = _pusSettings.Junta.JuntaGuid,
                JuntaId = _pusSettings.Junta.JuntaId,
                MostrarEnExpedicion = true,
                SeccionGuid = IsSeccionesReady ? Seccion.SeccionGuid : Guid.Empty,
                SeccionId = IsSeccionesReady ? Seccion.SeccionId : 0,
                Status = true,
            };
            AreaSeccion.MarkAsAdded();
            e.NewObject = AreaSeccion;
        }

        /// <summary>
        /// Identifica la sección de área seleccionada en la vista.
        /// </summary>
        private void SetCurrentAreaSeccion(object sender, EventArgs e)
        {
            BindingSource bindingSource = sender as BindingSource;
            if (bindingSource != null && bindingSource.Current != null)
                AreaSeccion = bindingSource.Current as AreaSeccion;
        }

        /// <summary>
        /// Ocurre cuando cambia de valor la propiedad AreaSecciones
        /// </summary>
        private void OnAreaSeccionesPropertyChanged()
        {
            _view.areaSeccionesBindingSource.DataSource = AreaSecciones;
            _view.areaSeccionesBindingSource.CurrentChanged += SetCurrentAreaSeccion;
            SetCurrentAreaSeccion(_view.areaSeccionesBindingSource, new EventArgs());
        }

        /// <summary>
        /// Se ejecuta cuando la propiedad AreaSeccion cambia de valor.
        /// </summary>
        private void OnAreaSeccionPropertyChanged()
        {
        }

        #endregion

    }
}
